from Base.baseData import DataBase
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import TimeoutException
from Base.baseLogger import Logger

logger = Logger('baseAutoWeb.py').getLogger()

# 针对定位法方法做封装
class WebBase(DataBase):

    def __init__(self,yamlName):
        super().__init__(yamlName)
        self.driver = self.gm.get_value('driver')
        self.t = 0.5
        self.timeout = 10

    def get_locator_data(self,locator,change_data=None):
        '''获取元组类型的元素数据login/pwd'''
        res = self.get_element_data(change_data)
        print(res)
        items = locator.split("/") #["login","password"]
        locat_data = tuple((res[items[0]][items[1]]))
        return locat_data

    def findElement(self, locator,change_data=None,timeout=10):
        """定位到元素，返回元素对象，没定位到，Timeout异常"""
        try:
            locator = self.get_locator_data(locator,change_data)
            if not isinstance(locator, tuple):
                logger.error('locator参数类型错误，必须传列表或元组类型：loc = ["id", "value1"]')
            logger.debug("正在定位元素信息：定位方式->%s, value值->%s" % (locator[0], locator[1]))
            ele = WebDriverWait(self.driver, timeout, self.t).until(EC.presence_of_element_located(locator))
            logger.debug("定位元素{}成功".format(locator))
            return ele
        except TimeoutException as e:
            logger.error('未定位到元素',locator)
            raise e

    def findElements(self, locator,change_data=None,timeout=10):
        try:
            locator = self.get_locator_data(locator,change_data)
            if not isinstance(locator, tuple):
                logger.error('locator参数类型错误，必须传列表或元组类型：loc = ["id", "value1"]')
            logger.debug("正在定位元素信息：定位方式->%s, value值->%s" % (locator[0], locator[1]))
            ele = WebDriverWait(self.driver, timeout, self.t).until(EC.presence_of_all_elements_located(locator))
            logger.debug("定位元素{}成功".format(locator))
            return ele
        except TimeoutException as e:
            logger.error('未定位到元素',locator)
            raise e
    # 元素操作方法
    def get_url(self, url):
        """打开url，最大化窗口"""
        self.driver.get(url)
        self.driver.maximize_window()
        logger.debug("浏览器访问请求地址：%s" % url)

    def click(self, locator,change_data=None):
        '''按钮点击'''
        try:
            ele = self.findElement(locator,change_data)
            ele.click()
            logger.debug('按钮点击 {} 成功'.format(locator))
        except Exception as e:
            logger.error('按钮点击 {} 失败'.format(locator))
            raise e

    def clear(self, locator,change_data=None):
        '''清空输入框'''
        try:
            ele = self.findElement(locator,change_data)
            ele.clear()
            logger.debug('清空输入框 {} 成功'.format(locator))
        except Exception as e:
            logger.error('清空输入框 {} 失败'.format(locator))
            raise e

    def sendKeys(self, locator, text='',change_data=None):
        '''输入文本'''
        try:
            ele = self.findElement(locator,change_data)
            ele.send_keys(text)
            logger.debug('输入文本 {} 成功'.format(text))
        except Exception as e:
            logger.error('输入文本 {} 失败'.format(text))
            raise e

    def get_title(self):
        """获取title"""
        try:
            title = self.driver.title
            logger.debug('获取title {} 成功'.format(title))
            return title
        except Exception as e:
            logger.error('获取title 失败')
            return ''

    def get_text(self, locator,change_data=None):
        """获取文本"""
        try:
            content = self.findElement(locator,change_data).text
            logger.debug('获取文本 {} 成功'.format(content))
            return content
        except:
            logger.error('获取文本 失败')
            return ""

    def get_attribute(self, locator, name,change_data=None):
        """获取属性"""
        try:
            element = self.findElement(locator,change_data)
            attr = element.get_attribute(name)
            logger.debug('获取属性 {} 成功'.format(attr))
            return attr
        except:
            logger.error('获取属性 失败')
            return ""

    def isSelected(self, locator,change_data=None):
        """判断元素是否被选中，返回bool值"""
        ele = self.findElement(locator,change_data)
        r = ele.is_selected()
        return r

    def is_title(self, _title=''):
        """返回bool值"""
        try:
            result = WebDriverWait(self.driver, self.timeout, self.t).until(EC.title_is(_title))
            print(result.get_attribute("innerHTML"))
            return result
        except:
            return False

    def is_title_contains(self, _title=''):
        """返回bool值"""
        try:
            result = WebDriverWait(self.driver, self.timeout, self.t).until(EC.title_contains(_title))
            return result
        except:
            return False

    def is_text_in_element(self, locator, _text='',change_data=None):
        """返回bool值"""
        try:
            locator = self.get_locator_data(locator,change_data)
            result = WebDriverWait(self.driver, self.timeout, self.t).until(EC.text_to_be_present_in_element(locator, _text))
            return result
        except:
            return False

    def is_value_in_element(self, locator, _value='',change_data=None):
        """返回bool值, value为空字符串，返回Fasle"""
        try:
            locator = self.get_locator_data(locator,change_data)
            result = WebDriverWait(self.driver, self.timeout, self.t).until(EC.text_to_be_present_in_element_value(locator, _value))
            return result
        except:
            return False

    def is_alert(self, timeout=3):
        """判断alert,存在返回alert实例，不存在，返回false"""
        try:
            result = WebDriverWait(self.driver, timeout, self.t).until(EC.alert_is_present())
            return result
        except:
            return False

    def mouse_move_to(self,locator,change_data=None):
        """鼠标悬停"""
        element = self.findElement(locator,change_data)
        ActionChains(self.driver).move_to_element(element).perform()
        logger.info('鼠标在{}元素悬停'.format(locator))

    def mouse_drag_to(self,locator,xoffset, yoffset,change_data=None):
        """鼠标拖拽到某一坐标"""
        element = self.findElement(locator,change_data)
        ActionChains(self.driver).drag_and_drop_by_offset(element, xoffset, yoffset)
        logger.info('鼠标在{}元素拖拽{}，{}'.format(locator,xoffset, yoffset))

    def js_focus_element(self, locator,change_data=None):
        """聚焦元素"""
        target = self.findElement(locator,change_data)
        self.driver.execute_script("arguments[0].scrollIntoView();", target)
        logger.info('聚焦元素{}'.format(locator))

    def js_scroll_top(self):
        """滚动到顶部"""
        js = "window.scrollTo(0,0)"
        self.driver.execute_script(js)
        logger.info('鼠标滑轮滚动到顶部')

    def js_scroll_end(self,x=0):
        """滚动到底部"""
        js = "window.scrollTo(%s,document.body.scrollHeight)"%x
        self.driver.execute_script(js) 
        logger.info('鼠标滑轮滚动到底部')

    def keyboard_send_keys_to(self,locator,text,change_data=None):
        """模拟键盘输入"""
        element = self.findElement(locator,change_data)
        ActionChains(self.driver).send_keys_to_element(element, text).perform()
        logger.info('键盘在{}位置输入：{}'.format(locator,text))

    def get_alert_text(self):
        '''获取弹窗文本'''
        confirm = self.driver.switch_to.alert
        logger.info('获取弹窗文本信息：{}'.format(confirm.text))
        return confirm.text

    def alert_accept(self):
        '''弹窗点击接受'''
        confirm = self.driver.switch_to.alert
        confirm.accept()
        logger.info('弹窗点击接收')

    def alert_dismiss(self):
        '''弹窗点击取消'''
        confirm = self.driver.switch_to.alert
        confirm.dismiss()
        logger.info('弹窗点击取消')

    def input_alert(self,text):
        '''弹窗输入'''
        prompt = self.driver.switch_to.alert
        prompt.send_keys(text)
        logger.info('弹窗输入文本值：{}'.format(text))

    def select_by_index(self, locator, index=0,change_data=None):
        """通过索引,index是索引第几个，从0开始，默认选第一个"""
        element = self.findElement(locator,change_data)  # 定位select这一栏
        Select(element).select_by_index(index)
        logger.info('选择{}位置的下拉列表的下拉项索引：{}'.format(locator,index))

    def select_by_value(self, locator, value,change_data=None):
        """通过value属性"""
        element = self.findElement(locator,change_data)
        Select(element).select_by_value(value)
        logger.info('选择{}位置的下拉列表的下拉项值：{}'.format(locator,value))

    def select_by_text(self, locator, text,change_data=None):
        """通过文本值定位"""
        element = self.findElement(locator,change_data)
        Select(element).select_by_visible_text(text)
        logger.info('选择{}位置的下拉列表的下拉项文本：{}'.format(locator,text))

    def switch_iframe(self, locator,change_data=None):
        """切换iframe"""
        try:
            id_index_locator = self.get_locator_data(locator,change_data)
            if isinstance(id_index_locator, int):
                self.driver.switch_to.frame(id_index_locator)
            elif isinstance(id_index_locator, str):
                self.driver.switch_to.frame(id_index_locator)
            elif isinstance(id_index_locator, tuple) or isinstance(id_index_locator, list):
                ele = self.findElement(locator)
                self.driver.switch_to.frame(ele)
            logger.info("iframe 切换为{}".format(id_index_locator))
        except Exception as e:
            logger.error("iframe{}切换异常,{}".format(locator,e))

    def switch_iframe_out(self):
        """切换iframe"""
        try:
            self.driver.switch_to.default_content()
            logger.info('iframe切换到最外层成功')
        except Exception as e:
            logger.error('iframe切换到最外层失败{}'.format(e))

    def switch_iframe_up(self):
        """切换iframe"""
        try:
            self.driver.switch_to.parent_frame()
            logger.info('iframe切换到上一层成功')
        except Exception as e:
            logger.error('iframe切换到上一层失败{}'.format(e))

    def get_handles(self):
        '''获取当前所有窗口'''
        try:
            handles = self.driver.window_handles
            logger.info('获取所有的handle：{}'.format(handles))
            return handles
        except Exception as e:
            logger.error('获取所有的handle失败{}'.format(e))

    def switch_handle(self, index=-1): #第几个，-1是最后一个
        '''切换窗口'''
        try:
            handle_list = self.driver.window_handles
            self.driver.switch_to.window(handle_list[index])
            logger.info('切换handle成功：{}'.format(index))
        except Exception as e:
            logger.error('切换handle失败{}'.format(e))


if __name__ == '__main__':
    web = WebBase('web元素信息')
    res = web.get_locator_data('login/welcome')
    print(res)






